#define  PRINTF_GLOBALS
#include "includes.h"


static void (* putchardata)(INT8U)=(void *)0;

void InItPrintf(void (* function_pr)(INT8U))
{
    putchardata =  function_pr;     
}

static void output_char(INT8U c)
{
	if(putchardata!=(void*)0){
    	(* putchardata)(c);
	}
}
/*********************************************************************************
**
**
**
*********************************************************************************/
static void printNum(INT32U num,INT16U base,INT16U sign,INT16U maxwidth,INT16U lead) 
{
    INT32U n;
    INT16U count;
    INT8U toPrint[64];
    if((sign==1)&&((long)num<0))
    {
        output_char('-');
        num=-num;
        if(maxwidth) maxwidth--;
    }
    count = 0;
    while((n=num/base)>0)
    {
        toPrint[count++]=(num-(n*base));
        num = n;
    }
    toPrint[count++] = num;
    
    if(maxwidth&&count<maxwidth)
    {
        for(n=maxwidth-count;n;n--)
        {
            output_char(lead);
        }
    }
    for(n=0;n<count;n++)
    {
        output_char("0123456789ABCDEF"[(int)(toPrint[count-(n+1)])]);
    }
    
}
/***************************************************************************
**
**
**
***************************************************************************/
void printk(const char *fmt,...)
{
   va_list  ap;
   INT8U  c,*str;
   INT16U  lflag,base,sign,width,lead;
   va_start(ap,fmt);
   for(;*fmt!='\0';fmt++)
   {
      lflag =0;base =0;sign =0;width =0;lead=' ';
	  if(*fmt=='%')
	  {
	     fmt++;
		 if(*fmt=='0')
		 {
            lead = '0';
			fmt++;
		 }
		 while(*fmt>='0'&&*fmt<='9')
		 {
            width *=10;
			width +=(*fmt-'0');
			fmt++;
		 }
		 if((c=*fmt)=='1')
		 {
            lflag =1;
			c=*++fmt;
		 }
		 switch(c)
		 {
            case 'b':
			case 'B': base = 2;  sign = 0;break;
			case 'o':
			case 'O': base = 8;  sign = 0;break;
			case 'd': 
			case 'D': base = 10; sign = 1;break;
			case 'u':
			case 'U': base = 10; sign = 0;break;
			case 'x':
			case 'X': base = 16; sign = 0;break;
			case 's': for(str =va_arg(ap,INT8U *);*str;str++)
				      output_char(*str);
			          break;
		    case 'c': output_char((INT8U )va_arg(ap,INT8U));
			          break;
			default:  output_char(c);
			          break;
     	 }
		 if(base)
		 printNum(lflag?va_arg(ap,long int):(long int)va_arg(ap,int),base,sign,width,lead);
	  }
	  else
	  output_char(*fmt);
   }
   va_end(ap);
}
/*******************************************************************************************/
INT8U *IntToStr(INT16U value,INT8U *buf)
{

     buf[0]=value/1000;
   	 buf[1]=(value-=buf[0]*1000)/100;
   	 buf[2]=(value-=buf[1]*100)/10;
   	 buf[3]=(value-=buf[2]*10);
   	 buf[0]|=0x30;
   	 buf[1]|=0x30;
   	 buf[2]|=0x30;
   	 buf[3]|=0x30;
   	 
   	 buf[4]='\0';
   	 return buf;
}
/*******************************************************************************************/
INT8U * Int2Str(INT16U value, INT8U * buf)
{
    INT8U cnt,i;
    INT8U temp;

    cnt=0;

    if(0 == value)
    {
        buf[0] = '0';
        buf[1] = '\0';
        return buf;
    }
    
    while(value)
    {
        buf[cnt] = (INT8U)(value%10 + '0');
        value /= 10;
        cnt++;
    }
    buf[cnt]='\0';

    i = 0;
    cnt--;
    while(cnt > i)
    {
        temp = buf[cnt];
        buf[cnt] = buf[i];
        buf[i] = temp;
        i++;
        cnt--;
    }

    return buf;
}

INT8U * Long2Str(INT32U value, INT8U * buf)
{
    INT8U cnt,i;
    INT8U temp;

    cnt=0;

    if(0 == value)
    {
        buf[0] = '0';
        buf[1] = '\0';
        return buf;
    }
    
    while(value)
    {
        buf[cnt] = (INT8U)(value%10 + '0');
        value /= 10;
        cnt++;
    }
    buf[cnt]='\0';

    i = 0;
    cnt--;
    while(cnt > i)
    {
        temp = buf[cnt];
        buf[cnt] = buf[i];
        buf[i] = temp;
        i++;
        cnt--;
    }

    return buf;
}

/**************************************************************************/
